package mfuny.ggongal.admin.users;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import mfuny.ggongal.admin.Server;
import mfuny.ggongal.admin.json.JsonCreater;

import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.springframework.web.servlet.ModelAndView;

import com.ibatis.sqlmap.client.SqlMapClient;

public class UserService {
	
	SqlMapClient sqlMapper;
	ModelAndView mav;
	JsonCreater jc;
	
	public UserService() throws Exception {
		sqlMapper = Server.getSqlMapper( );
		mav = new ModelAndView();
		jc = new JsonCreater();
	}
	
	//나이대 구하기.
	@SuppressWarnings( "deprecation" )
	public static String getAges(String birth_y) {
		int birthYear = Integer.parseInt( birth_y );
		int age = new Date().getYear( ) + 1900 - birthYear + 1;
		StringBuffer sb = new StringBuffer( String.valueOf( age ));
		sb.setCharAt( sb.length( ) - 1, '0' );
		
		return sb.toString( );
	}
	
	//회원가입 현황.
	public ModelAndView userRegReport() throws Exception {
		mav.clear( );
		mav.setViewName( "/users/userRegReport.ga" );
		return mav;
	}
	
	//누적 가입자.
	@SuppressWarnings( "unchecked" )
	public ModelAndView userRegReport_all() throws Exception {
		List<HashMap<String, Object>> userList = sqlMapper.queryForList( "user_targetAll", null );
		HashMap<String, Object> userMap = getTargetCountByMap( userList );
		mav.clear( );
		mav.setViewName( "/users/userRegReport_all" );
		mav.addObject( "userMap", userMap );
		return mav;
	}
	
	//월별 가입자.
	@SuppressWarnings( "unchecked" )
	public ModelAndView userRegReport_month(int year, int month) throws Exception {
		String startDay = year + "-" + month + "-1";
		String endDay = year + "-" + (month+1) + "-1";
		HashMap<String, String> paramMap = new HashMap<String, String>();
		paramMap.put( "startDay", startDay );
		paramMap.put( "endDay", endDay );
		List<HashMap<String, Object>> userList = sqlMapper.queryForList( "user_targetByDate", paramMap );
		HashMap<String, Object> userMap = getTargetCountByMap( userList );
		mav.clear( );
		mav.setViewName( "/users/userRegReport_month" );
		mav.addObject( "userMap", userMap );
		return mav;
	}
	
	//일별 가입자.
	@SuppressWarnings( { "deprecation", "unchecked" } )
	public ModelAndView userRegReport_day(String day) throws Exception {
		String[] dateStr = day.split( "-" );
		Date date = new Date( Integer.parseInt( dateStr[0] ) - 1900, Integer.parseInt( dateStr[1] ) - 1, Integer.parseInt( dateStr[2] ) );
		date.setDate( date.getDate( ) + 1 );
		String endDay = ( date.getYear( ) + 1900 ) + "-" + ( date.getMonth( ) + 1 ) + "-" + date.getDate( );
		
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put( "startDay", day );
		paramMap.put( "endDay", endDay );
		List<HashMap<String, Object>> userList = sqlMapper.queryForList( "user_targetByDate", paramMap );
		HashMap<String, Object> userMap = getTargetCountByMap( userList );
		
		mav.clear( );
		mav.setViewName( "/users/userRegReport_day" );
		mav.addObject( "userMap", userMap );
		return mav;
	}
	
	//유저 검색 페이지.
	public ModelAndView userSearch() throws Exception {
		mav.clear( );
		mav.setViewName( "/users/userSearch.ga" );
		return mav;
	}
	
	//유저 검색 디테일.
	@SuppressWarnings( "unchecked" )
	public ModelAndView userSearch_detail( String param ) throws Exception {
		JSONObject jsonParam = (JSONObject)JSONValue.parse( param );
		List<UserDao> userList = new ArrayList<UserDao>();
		
		if ( jsonParam.get( "tag" ).equals( "name" ) ) {
			userList = sqlMapper.queryForList( "user_selectByName", jsonParam );
		} else if ( jsonParam.get( "tag" ).equals( "id" )) {
			userList = sqlMapper.queryForList( "user_selectByIdMap", jsonParam );
		}
		
		mav.clear( );
		mav.setViewName( "/users/userSearch_detail" );
		mav.addObject( "userList", userList );
		return mav;
	}
	
	//유저 검색 디테일 팝업.
	public ModelAndView userSearch_detailPopup(String id) throws Exception {
		UserDao user = (UserDao) sqlMapper.queryForObject("user_selectById", id);
		
		mav.clear();
		mav.setViewName("/users/userSearch_detailPopup");
		mav.addObject("user", user);
		return mav;
	}
	
	//특정 유저 꽁 적립 차감 내역.
	@SuppressWarnings("unchecked")
	public ModelAndView userSearch_detailGgong(String id, int type, int page) throws Exception {
		String sqlId = "";
		String totalSqlId = "";
		
		switch(type) {
		case 0:
			sqlId = "myggong_selectById";
			totalSqlId = "myggong_countById";
			break;
		case 1:
			sqlId = "myggong_selectById1";
			totalSqlId = "myggong_countById1";
			break;
		case 2:
			sqlId = "myggong_selectById2";
			totalSqlId = "myggong_countById2";
			break;
		}
		
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("id", id);
		paramMap.put("start", page == 1 ? 0 : page * 10 - 10);
		List<HashMap<String, Object>> myGgongList = sqlMapper.queryForList(sqlId, paramMap);
		int totalCount = (Integer)sqlMapper.queryForObject(totalSqlId, id);
		
		mav.clear();
		mav.setViewName("users/userSearch_detailGgong");
		mav.addObject("myGgongList", myGgongList);
		mav.addObject("page", page);
		mav.addObject("total", totalCount);
		return mav;
	}
	
	//유저 정보 변경폼.
	public ModelAndView userSearch_modifyForm(String id) throws Exception {
		UserDao user = (UserDao) sqlMapper.queryForObject("user_selectById", id);
		mav.clear();
		mav.setViewName("/users/userSearch_modifyForm");
		mav.addObject("user", user);
		return mav;
	}
	
	//유저 정보 변경처리.
	public ModelAndView userSearch_modify(UserDao userDao) throws Exception {
		int result = sqlMapper.update("user_infoUpdateByAdmin", userDao);
		String msg = "문제가 발생하였습니다. 나중에 다시 시도해주세요.";
		if(result > 0) {
			msg = "정상적으로 처리되었습니다.";
		}
		mav.clear();
		mav.setViewName("/popupClose_msg");
		mav.addObject("msg", msg);
		return mav;
	}
	
	//타겟별 count 구하기(파라미터 List).
	@SuppressWarnings( { "unchecked", "rawtypes" } )
	public HashMap<String, Object> getTargetCount(List<UserDao> userList) {
		HashMap targetCount = new HashMap();
		HashMap[] map = new HashMap[6];
		for ( int i = 0; i < map.length; i++ ) {
			map[i] = new HashMap();
		}
		
		for( int i = 0; i < userList.size( ); i++ ) {
			UserDao userDao = userList.get( i );
			
			//토탈.
			if ( map[0].containsKey( "all" )) {
				int count = (Integer)map[0].get( "all" ) + 1;
				map[0].put( "all", count );
			} else {
				map[0].put( "all", 1 );
			}
			
			//성별.
			if ( map[1].containsKey( userDao.getSex( ) ) ) {
				int count = (Integer)map[1].get( userDao.getSex( ) ) + 1;
				map[1].put( userDao.getSex( ), count );
			} else {
				map[1].put( userDao.getSex( ), 1 );
			}
			
			//결혼유무.
			if ( map[2].containsKey( "marry_" + userDao.getMarry( ) )) {
				int count = (Integer)map[2].get( "marry_" + userDao.getMarry( ) ) + 1;
				map[2].put( "marry_" + userDao.getMarry( ), count );
			} else {
				map[2].put( "marry_" + userDao.getMarry( ), 1 );
			}
			
			//지역.
			if ( map[3].containsKey( userDao.getArea( ) )) {
				int count = (Integer)map[3].get( userDao.getArea( ) ) + 1;
				map[3].put( userDao.getArea( ), count );
			} else {
				map[3].put( userDao.getArea( ), 1 );
			}
			
			//직업.
			if ( map[4].containsKey( userDao.getJob( ) )) {
				int count = (Integer)map[4].get( userDao.getJob( ) ) + 1;
				map[4].put( userDao.getJob( ), count );
			} else {
				map[4].put( userDao.getJob( ), 1 );
			}
			
			//나이.
			String ages = getAges( userDao.getBirth_y( ) );
			if ( map[5].containsKey( ages )) {
				int count = (Integer)map[5].get( ages ) + 1;
				map[5].put( ages, count );
			} else {
				map[5].put( ages, 1 );
			}
		}
		
		targetCount.put( "user", map[0] );
		targetCount.put( "sex", map[1] );
		targetCount.put( "marry", map[2] );
		targetCount.put( "area", map[3] );
		targetCount.put( "job", map[4] );
		targetCount.put( "age", map[5] );
		
		return targetCount;
	}
	
	// 타겟별 count 구하기(파라미터 HashMap).
	@SuppressWarnings( { "unchecked", "rawtypes", "deprecation" } )
	public HashMap<String, Object> getTargetCountByMap( List<HashMap<String, Object>> userList ) {
		HashMap targetCount = new HashMap( );
		HashMap[ ] map = new HashMap[7];
		for ( int i = 0; i < map.length; i++ ) {
			map[ i ] = new HashMap( );
		}

		for ( int i = 0; i < userList.size( ); i++ ) {
			HashMap<String, Object> userMap = (HashMap<String, Object>)userList.get( i );

			// 토탈.
			if ( map[ 0 ].containsKey( "all" ) ) {
				int count = (Integer)map[ 0 ].get( "all" ) + 1;
				map[ 0 ].put( "all", count );
			} else {
				map[ 0 ].put( "all", 1 );
			}

			// 성별.
			if ( map[ 1 ].containsKey( userMap.get( "sex" ) ) ) {
				int count = (Integer)map[ 1 ].get( userMap.get( "sex" ) ) + 1;
				map[ 1 ].put( userMap.get( "sex" ), count );
			} else {
				map[ 1 ].put( userMap.get( "sex" ), 1 );
			}

			// 결혼유무.
			if ( map[ 2 ].containsKey( "marry_" + userMap.get( "marry" ) ) ) {
				int count = (Integer)map[ 2 ].get( "marry_" + userMap.get( "marry" ) ) + 1;
				map[ 2 ].put( "marry_" + userMap.get( "marry" ), count );
			} else {
				map[ 2 ].put( "marry_" + userMap.get( "marry" ), 1 );
			}

			// 지역.
			if ( map[ 3 ].containsKey( userMap.get( "area" ) ) ) {
				int count = (Integer)map[ 3 ].get( userMap.get( "area" ) ) + 1;
				map[ 3 ].put( userMap.get( "area" ), count );
			} else {
				map[ 3 ].put( userMap.get( "area" ), 1 );
			}

			// 직업.
			if ( map[ 4 ].containsKey( userMap.get( "job" ) ) ) {
				int count = (Integer)map[ 4 ].get( userMap.get( "job" ) ) + 1;
				map[ 4 ].put( userMap.get( "job" ), count );
			} else {
				map[ 4 ].put( userMap.get( "job" ), 1 );
			}

			// 나이.
			String ages = getAges( (String)userMap.get( "birth_y" ) );
			if ( map[ 5 ].containsKey( ages ) ) {
				int count = (Integer)map[ 5 ].get( ages ) + 1;
				map[ 5 ].put( ages, count );
			} else {
				map[ 5 ].put( ages, 1 );
			}
			
			//가입날짜별.
			Timestamp ts = (Timestamp)userMap.get( "regdate" );
			int day = ts.getDate( );
			
			if ( map[ 6 ].containsKey( day )) {
				int count = (Integer)map[ 6 ].get( day ) + 1;
				map[6].put( day, count );
			} else {
				map[6].put( day, 1 );
			}
		}

		targetCount.put( "user", map[ 0 ] );
		targetCount.put( "sex", map[ 1 ] );
		targetCount.put( "marry", map[ 2 ] );
		targetCount.put( "area", map[ 3 ] );
		targetCount.put( "job", map[ 4 ] );
		targetCount.put( "age", map[ 5 ] );
		targetCount.put( "regdate", map[ 6 ] );

		return targetCount;
	}
}
